package com.quiz.bis.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.therapi.runtimejavadoc.repack.com.eclipsesource.json.Json;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.quiz.bis.domain.bo.ScoreAppealBo;
import com.quiz.bis.domain.bo.ScoreQueryBo;
import com.quiz.bis.domain.model.*;
import com.quiz.bis.domain.vo.*;
import com.quiz.bis.mapper.*;
import com.quiz.bis.service.IScoreService;
import com.quiz.bis.service.IScoreStudentService;
import com.quiz.common.core.domain.R;
import com.quiz.common.core.domain.entity.SysUser;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.mybatis.core.page.PageQuery;
import com.quiz.common.mybatis.core.page.TableDataInfo;
import com.quiz.common.mybatis.core.query.MPJLambdaWrapperPlus;
import com.quiz.common.utils.SecurityUtils;
import com.quiz.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 成绩管理服务实现
 */
@Service
@RequiredArgsConstructor
public class ScoreStudentServiceImpl implements IScoreStudentService {
    private final ExamMapper examMapper;
    private final ExamStudentRecordMapper recordMapper;
    private final ExamQuestionAnswersMapper questionAnswersMapper;
    private final PaperMapper paperMapper;
    private final PaperQuestionMapper paperQuestionMapper;
    private final QuestionMapper questionMapper;
    private final QuestionTypeMapper questionTypeMapper;
    private final QuestionOptionMapper optionMapper;
    private final QuestionAnswerMapper answerMapper;
    private final SysUserMapper userMapper;
    private final ExamScoreAppealsMapper appealsMapper;
    private final ExamGroupMemberMapper groupMembersMapper;
    private final QuestionCategoryRelationMapper questionCategoryRelationMapper;
    private final QuestionCategoryMapper questionCategoryMapper;

    @Override
    public TableDataInfo<StudentScoreVo2> pageStudentScoreList(ScoreQueryBo query, PageQuery pageQuery) {
        // 验证当前用户是否属于该考试组
        Long userId = SecurityUtils.getUserId();
        boolean isMember = groupMembersMapper.exists(
                Wrappers.lambdaQuery(ExamGroupMember.class)
                        .eq(ExamGroupMember::getExamGroupId, query.getGroupId())
                        .eq(ExamGroupMember::getUserId, userId)
                        .eq(ExamGroupMember::getApproveStatus, 1) // 已通过
        );

        if (!isMember) {
            throw new ServiceException("您不属于该考试组，无法查看成绩");
        }

        // 查询已结束且已发布成绩的考试
        Page<Exam> page = examMapper.selectStudentPubedExamPage(
                pageQuery.build(),
                query.getGroupId(),
                query.getType(),
                SecurityUtils.getUserId(),
                query.getSearchKey()
        );

        // 转换为VO
        List<StudentScoreVo2> vos = page.getRecords().stream().map(exam -> {
            StudentScoreVo2 vo = new StudentScoreVo2();
            vo.setId(exam.getId().toString());
            vo.setActivityName(exam.getTitle());
            vo.setType(exam.getType());
            vo.setStatus(exam.getStatus());

            // 获取学生考试记录
            ExamStudentRecord record = recordMapper.selectOne(
                    Wrappers.lambdaQuery(ExamStudentRecord.class)
                            .eq(ExamStudentRecord::getExamId, exam.getId())
                            .eq(ExamStudentRecord::getUserId, userId)
            );

            if (record != null) {
                vo.setRecordId(record.getId().toString());
                vo.setScore(record.getScore());
                vo.setSubmitTime(record.getSubmitTime());


                // 计算用时
                if (record.getStartTime() != null && record.getSubmitTime() != null) {
                    long minutes = (record.getSubmitTime().getTime() - record.getStartTime().getTime()) / (1000 * 60);
                    vo.setTimeUsed((int) minutes);
                }

                // 获取试卷信息
                Paper paper = paperMapper.selectById(exam.getPaperId());
                if (paper != null) {
                    vo.setTotalScore(paper.getTotalScore());
                    // 计算正确率
                    if (record.getScore() != null && paper.getTotalScore().compareTo(BigDecimal.ZERO) > 0) {
                        BigDecimal correctRate = record.getScore()
                                .divide(paper.getTotalScore(), 4, RoundingMode.HALF_UP)
                                .multiply(new BigDecimal(100))
                                .setScale(2, RoundingMode.HALF_UP);
                        vo.setCorrectRate(correctRate);
                    }
                }
            }

            return vo;
        }).collect(Collectors.toList());

        return TableDataInfo.build(vos, page.getTotal());
    }

    @Override
    public StudentExamScoreDetailVo2 getStudentScoreDetail(Long recordId) {
        // 验证记录归属
        ExamStudentRecord record = recordMapper.selectById(recordId);
        if (record == null) {
            throw new ServiceException("考试记录不存在");
        }

        Long userId = SecurityUtils.getUserId();
        if (!record.getUserId().equals(userId)) {
            throw new ServiceException("无权查看他人成绩");
        }

        StudentExamScoreDetailVo2 vo = new StudentExamScoreDetailVo2();
        vo.setId(record.getId().toString());
        vo.setUserId(record.getUserId());
        vo.setScore(record.getScore());
        vo.setSubmitTime(record.getSubmitTime());

        // 获取考试信息
        Exam exam = examMapper.selectById(record.getExamId());
        if (exam != null) {
            vo.setActivityName(exam.getTitle());
            vo.setType(exam.getType());

            // 获取试卷信息
            Paper paper = paperMapper.selectById(exam.getPaperId());
            if (paper != null) {
                vo.setTotalScore(paper.getTotalScore());
                // 计算正确率
                if (record.getScore() != null && paper.getTotalScore().compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal correctRate = record.getScore()
                            .divide(paper.getTotalScore(), 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal(100))
                            .setScale(2, RoundingMode.HALF_UP);
                    vo.setCorrectRate(correctRate);
                }
            }
        }

        // 获取用户信息
        SysUser user = userMapper.selectUserById(userId);
        if (user != null) {
            vo.setUserName(user.getUserName());
            vo.setNickName(user.getNickName());
        }

        // 获取题目作答详情
        List<ExamQuestionAnswers> answers = questionAnswersMapper.selectList(
                Wrappers.lambdaQuery(ExamQuestionAnswers.class)
                        .eq(ExamQuestionAnswers::getStudentRecordId, recordId)
        );

        // 获取题目信息
        List<Long> questionIds = answers.stream()
                .map(ExamQuestionAnswers::getQuestionId)
                .collect(Collectors.toList());
        Map<Long, Question> questionMap = questionMapper.selectBatchIds(questionIds).stream()
                .collect(Collectors.toMap(Question::getId, q -> q));

        // 获取题型信息
        List<Long> typeIds = questionMap.values().stream()
                .map(Question::getTypeId)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, QuestionType> typeMap = questionTypeMapper.selectBatchIds(typeIds).stream()
                .collect(Collectors.toMap(QuestionType::getId, t -> t));

        // 获取选项信息
        Map<Long, List<QuestionOption>> optionMap = optionMapper.selectList(
                Wrappers.lambdaQuery(QuestionOption.class)
                        .in(QuestionOption::getQuestionId, questionIds)
        ).stream().collect(Collectors.groupingBy(QuestionOption::getQuestionId));

        // 获取答案信息
        Map<Long, List<QuestionAnswer>> answerMap = answerMapper.selectList(
                Wrappers.lambdaQuery(QuestionAnswer.class)
                        .in(QuestionAnswer::getQuestionId, questionIds)
        ).stream().collect(Collectors.groupingBy(QuestionAnswer::getQuestionId));

        // 构建题目详情VO
        List<StudentQuestionDetailVo2> questionDetails = answers.stream().map(answer -> {
            StudentQuestionDetailVo2 detail = new StudentQuestionDetailVo2();
            detail.setId(answer.getId());
            detail.setQuestionId(answer.getQuestionId());
            detail.setScore(answer.getScore());
            detail.setMaxScore(answer.getMaxScore());
            detail.setIsCorrect(answer.getIsCorrect());
            detail.setAnswerContent(answer.getAnswerContent());
            List<String> selectedOptionCodes = JSON.parseArray(answer.getSelectedOptionCodes(), String.class);
            detail.setSelectedOptionCodes(selectedOptionCodes);
            detail.setCorrectComment(answer.getCorrectComment());

            // 设置是否可以申诉
            detail.setCanAppeal(answer.getScoreStatus() == 2 && // 人工批改完成
                    answer.getAppealStatus() == 0 && // 未申诉
                    (answer.getScore() == null ||
                            answer.getScore().compareTo(answer.getMaxScore()) < 0)); // 未得满分

            Question question = questionMap.get(answer.getQuestionId());
            if (question != null) {
                detail.setContent(question.getContent());
                detail.setTypeId(question.getTypeId());

                QuestionType type = typeMap.get(question.getTypeId());
                if (type != null) {
                    detail.setTypeName(type.getName());
                }

                // 设置选项
                if (optionMap.containsKey(question.getId())) {
                    List<QuestionOption> options = optionMap.get(question.getId());
                    detail.setOptions(options.stream().map(opt -> {
                        QuestionOptionVo optVo = new QuestionOptionVo();
                        optVo.setId(opt.getId());
                        optVo.setOptionCode(opt.getOptionCode());
                        optVo.setContent(opt.getContent());
                        optVo.setIsCorrect(opt.getIsCorrect());
                        optVo.setSelected(answer.getSelectedOptionCodes() != null &&
                                answer.getSelectedOptionCodes().contains(opt.getOptionCode()));
                        return optVo;
                    }).collect(Collectors.toList()));
                }

                // 设置参考答案
                if (answerMap.containsKey(question.getId())) {
                    List<QuestionAnswer> answersList = answerMap.get(question.getId());
                    detail.setCorrectAnswer(answersList.stream()
                            .map(QuestionAnswer::getContent)
                            .collect(Collectors.joining("<br>")));
                }

                // 设置解析
                detail.setAnalysis(question.getAnalysis());
            }

            return detail;
        }).collect(Collectors.toList());

        vo.setQuestions(questionDetails);

        // 获取统计信息
        vo.setStatistics(this.getExamStatistics(record.getExamId(), userId));
        vo.setTypeScores(this.getTypeScores(recordId));
        vo.setDifficultyScores(this.getDifficultyScores(recordId));
        vo.setKnowledgeScores(this.getKnowledgeScores(recordId));

        return vo;
    }

    // 新增三个统计方法
    private List<TypeScoreVo> getTypeScores(Long recordId) {
        List<ExamQuestionAnswers> answers = questionAnswersMapper.selectList(
                Wrappers.lambdaQuery(ExamQuestionAnswers.class)
                        .eq(ExamQuestionAnswers::getStudentRecordId, recordId)
        );

        // 获取题目和题型信息
        List<Long> questionIds = answers.stream()
                .map(ExamQuestionAnswers::getQuestionId)
                .collect(Collectors.toList());
        Map<Long, Question> questionMap = questionMapper.selectBatchIds(questionIds).stream()
                .collect(Collectors.toMap(Question::getId, q -> q));
        Map<Long, QuestionType> typeMap = questionTypeMapper.selectBatchIds(
                questionMap.values().stream().map(Question::getTypeId).distinct().collect(Collectors.toList())
        ).stream().collect(Collectors.toMap(QuestionType::getId, t -> t));

        // 按题型分组统计
        Map<Long, TypeScoreVo> typeScoreMap = new HashMap<>();
        answers.forEach(answer -> {
            Question question = questionMap.get(answer.getQuestionId());
            if (question != null) {
                QuestionType type = typeMap.get(question.getTypeId());
                if (type != null) {
                    TypeScoreVo typeScore = typeScoreMap.computeIfAbsent(type.getId(), k -> {
                        TypeScoreVo vo = new TypeScoreVo();
                        vo.setTypeId(type.getId());
                        vo.setTypeName(type.getName());
                        vo.setTotalScore(BigDecimal.ZERO);
                        vo.setMaxScore(BigDecimal.ZERO);
                        return vo;
                    });
                    typeScore.setTotalScore(typeScore.getTotalScore().add(answer.getScore()));
                    typeScore.setMaxScore(typeScore.getMaxScore().add(answer.getMaxScore()));
                }
            }
        });

        // 计算百分比
        typeScoreMap.values().forEach(vo -> {
            if (vo.getMaxScore().compareTo(BigDecimal.ZERO) > 0) {
                vo.setPercentage(vo.getTotalScore()
                        .divide(vo.getMaxScore(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100")));
            } else {
                vo.setPercentage(BigDecimal.ZERO);
            }
        });

        return new ArrayList<>(typeScoreMap.values());
    }

    private List<DifficultyScoreVo> getDifficultyScores(Long recordId) {
        List<ExamQuestionAnswers> answers = questionAnswersMapper.selectList(
                Wrappers.lambdaQuery(ExamQuestionAnswers.class)
                        .eq(ExamQuestionAnswers::getStudentRecordId, recordId)
        );

        // 获取题目信息
        List<Long> questionIds = answers.stream()
                .map(ExamQuestionAnswers::getQuestionId)
                .collect(Collectors.toList());
        Map<Long, Question> questionMap = questionMapper.selectBatchIds(questionIds).stream()
                .collect(Collectors.toMap(Question::getId, q -> q));

        // 按难度分组统计
        Map<Integer, DifficultyScoreVo> difficultyScoreMap = new HashMap<>();
        answers.forEach(answer -> {
            Question question = questionMap.get(answer.getQuestionId());
            if (question != null && question.getDifficult() != null) {
                DifficultyScoreVo difficultyScore = difficultyScoreMap.computeIfAbsent(
                        question.getDifficult(), k -> {
                            DifficultyScoreVo vo = new DifficultyScoreVo();
                            vo.setDifficulty(k);
                            vo.setDifficultyName(getDifficultyName(k));
                            vo.setTotalScore(BigDecimal.ZERO);
                            vo.setMaxScore(BigDecimal.ZERO);
                            return vo;
                        });
                difficultyScore.setTotalScore(difficultyScore.getTotalScore().add(answer.getScore()));
                difficultyScore.setMaxScore(difficultyScore.getMaxScore().add(answer.getMaxScore()));
            }
        });

        // 计算百分比
        difficultyScoreMap.values().forEach(difficultyVo -> {
            if (difficultyVo.getMaxScore().compareTo(BigDecimal.ZERO) > 0) {
                difficultyVo.setPercentage(difficultyVo.getTotalScore()
                        .divide(difficultyVo.getMaxScore(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100")));
            } else {
                difficultyVo.setPercentage(BigDecimal.ZERO);
            }
        });

        return new ArrayList<>(difficultyScoreMap.values());
    }

    private List<KnowledgeScoreVo> getKnowledgeScores(Long recordId) {
        List<ExamQuestionAnswers> answers = questionAnswersMapper.selectList(
                Wrappers.lambdaQuery(ExamQuestionAnswers.class)
                        .eq(ExamQuestionAnswers::getStudentRecordId, recordId)
        );

        // 获取题目和知识点关联信息
        List<Long> questionIds = answers.stream()
                .map(ExamQuestionAnswers::getQuestionId)
                .collect(Collectors.toList());
        List<QuestionCategoryRelation> relations = questionCategoryRelationMapper.selectList(
                Wrappers.lambdaQuery(QuestionCategoryRelation.class)
                        .in(QuestionCategoryRelation::getQuestionId, questionIds)
        );
        Map<Long, List<Long>> questionKnowledgeMap = relations.stream()
                .collect(Collectors.groupingBy(
                        QuestionCategoryRelation::getQuestionId,
                        Collectors.mapping(QuestionCategoryRelation::getCategoryId, Collectors.toList())
                ));

        // 获取知识点信息
        List<Long> knowledgeIds = relations.stream()
                .map(QuestionCategoryRelation::getCategoryId)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, QuestionCategory> knowledgeMap = knowledgeIds.isEmpty() ?
                Collections.emptyMap() :
                questionCategoryMapper.selectBatchIds(knowledgeIds).stream()
                        .collect(Collectors.toMap(QuestionCategory::getId, k -> k));

        // 按知识点分组统计
        Map<Long, KnowledgeScoreVo> knowledgeScoreMap = new HashMap<>();
        answers.forEach(answer -> {
            List<Long> knowledgeIdsForQuestion = questionKnowledgeMap.getOrDefault(
                    answer.getQuestionId(), Collections.emptyList());
            knowledgeIdsForQuestion.forEach(knowledgeId -> {
                QuestionCategory knowledge = knowledgeMap.get(knowledgeId);
                if (knowledge != null) {
                    KnowledgeScoreVo knowledgeScore = knowledgeScoreMap.computeIfAbsent(
                            knowledgeId, k -> {
                                KnowledgeScoreVo vo = new KnowledgeScoreVo();
                                vo.setKnowledgeId(k);
                                vo.setKnowledgeName(knowledge.getName());
                                vo.setTotalScore(BigDecimal.ZERO);
                                vo.setMaxScore(BigDecimal.ZERO);
                                return vo;
                            });
                    knowledgeScore.setTotalScore(knowledgeScore.getTotalScore().add(answer.getScore()));
                    knowledgeScore.setMaxScore(knowledgeScore.getMaxScore().add(answer.getMaxScore()));
                }
            });
        });

        // 计算百分比
        knowledgeScoreMap.values().forEach(knowledgeVo -> {
            if (knowledgeVo.getMaxScore().compareTo(BigDecimal.ZERO) > 0) {
                knowledgeVo.setPercentage(knowledgeVo.getTotalScore()
                        .divide(knowledgeVo.getMaxScore(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100")));
            } else {
                knowledgeVo.setPercentage(BigDecimal.ZERO);
            }
        });

        return new ArrayList<>(knowledgeScoreMap.values());
    }

    private String getDifficultyName(Integer difficulty) {
        if (difficulty == null) {
            return "未知";
        }
        switch (difficulty) {
            case 1:
                return "容易";
            case 2:
                return "偏易";
            case 3:
                return "中等";
            case 4:
                return "偏难";
            case 5:
                return "困难";
            default:
                return "未知";
        }
    }

    @Override
    @Transactional
    public R<Void> submitAppeal(ScoreAppealBo appealBo) {
        // 验证记录归属
        ExamStudentRecord record = recordMapper.selectById(appealBo.getRecordId());
        if (record == null) {
            return R.fail("考试记录不存在");
        }

        Long userId = SecurityUtils.getUserId();
        if (!record.getUserId().equals(userId)) {
            return R.fail("无权操作他人记录");
        }

        // 验证题目作答记录
        ExamQuestionAnswers answer = questionAnswersMapper.selectById(appealBo.getQuestionAnswerId());
        if (answer == null || !answer.getStudentRecordId().equals(appealBo.getRecordId())) {
            return R.fail("题目作答记录不存在");
        }

        // 验证是否已经申诉过
        if (answer.getAppealStatus() != 0) {
            return R.fail("该题目已申诉过，不能重复申诉");
        }

        // 创建申诉记录
        ExamScoreAppeals appeal = new ExamScoreAppeals();
        appeal.setGroupId(appealBo.getGroupId());
        appeal.setExamId(record.getExamId());
        appeal.setStudentRecordId(appealBo.getRecordId());
        appeal.setQuestionAnswerId(appealBo.getQuestionAnswerId());
        appeal.setStudentId(userId);
        appeal.setAppealContent(appealBo.getContent());
        appeal.setAppealTime(new Date());
        appeal.setAppealStatus(0); // 待处理
        appeal.setQuestionId(answer.getQuestionId());
        appeal.setDeptId(SecurityUtils.getDeptId());
        appealsMapper.insert(appeal);

        // 更新题目作答记录的申诉状态
        ExamQuestionAnswers updateAnswer = new ExamQuestionAnswers();
        updateAnswer.setId(appealBo.getQuestionAnswerId());
        updateAnswer.setAppealStatus(1); // 申诉中
        questionAnswersMapper.updateById(updateAnswer);

        return R.ok();
    }

    /**
     * private Long id;
     * private String examName;
     * private Integer examType;
     * private String questionContent;
     * private Integer status;
     * @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     * private Date appealTime;
     * @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     * private Date handleTime;
     * private String handlerName;
     * private String answerContent;
     * private String correctAnswer;
     * private String appealContent;
     * private String handleResult;
     * private BigDecimal oldScore;
     * private BigDecimal newScore;
     */
    @Override
    public TableDataInfo<StudentAppealVo> getStudentAppealList(Long groupId, PageQuery pageQuery) {
        MPJLambdaWrapper<ExamScoreAppeals> wrapper = new MPJLambdaWrapperPlus<>(ExamScoreAppeals.class)
                .selectAll(ExamScoreAppeals.class)
                .selectAs(ExamScoreAppeals::getAppealStatus, "status")
                .selectAs(Exam::getTitle, "examName")
                .selectAs(Exam::getType, "examType")
                .selectAs(Question::getContent, "questionContent")
                .selectAs(SysUser::getNickName, "handlerName")
                .selectAs(ExamQuestionAnswers::getAnswerContent, "answerContent")
                .selectAs(QuestionAnswer::getContent, "correctAnswer")
                .selectAs(ExamQuestionAnswers::getScore, "newScore")
                .leftJoin(Exam.class, Exam::getId, ExamScoreAppeals::getExamId)
                .leftJoin(ExamQuestionAnswers.class, ExamQuestionAnswers::getId, ExamScoreAppeals::getQuestionAnswerId)
                .leftJoin(Question.class, Question::getId, ExamScoreAppeals::getQuestionId)
                .leftJoin(QuestionAnswer.class, QuestionAnswer::getQuestionId, ExamScoreAppeals::getQuestionId)
                .leftJoin(SysUser.class, SysUser::getUserId, ExamScoreAppeals::getHandlerId)
                .eq(ExamScoreAppeals::getGroupId, groupId)
                .eq(ExamScoreAppeals::getStudentId, SecurityUtils.getUserId());
        Page<StudentAppealVo> page = appealsMapper.selectJoinPage(pageQuery.build(), StudentAppealVo.class, wrapper);
        return TableDataInfo.build(page);
    }

    /**
     * 获取考试统计信息
     */
    private ExamStatisticsVo getExamStatistics(Long examId, Long userId) {
        ExamStatisticsVo statistics = new ExamStatisticsVo();

        // 获取所有学生记录
        List<ExamStudentRecord> records = recordMapper.selectList(
                Wrappers.lambdaQuery(ExamStudentRecord.class)
                        .eq(ExamStudentRecord::getExamId, examId)
                        .eq(ExamStudentRecord::getStatus, 2) // 已提交
        );

        if (!records.isEmpty()) {
            // 基本统计
            statistics.setTotal(Long.valueOf(records.size()));

            // 分数统计
            BigDecimal sumScore = records.stream()
                    .map(ExamStudentRecord::getScore)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            statistics.setAvgScore(sumScore.divide(new BigDecimal(records.size()), 2, RoundingMode.HALF_UP));

            statistics.setHighestScore(records.stream()
                    .map(ExamStudentRecord::getScore)
                    .filter(Objects::nonNull)
                    .max(Comparator.naturalOrder())
                    .orElse(BigDecimal.ZERO));

            statistics.setLowestScore(records.stream()
                    .map(ExamStudentRecord::getScore)
                    .filter(Objects::nonNull)
                    .min(Comparator.naturalOrder())
                    .orElse(BigDecimal.ZERO));

            // 通过率
            Exam exam = examMapper.selectById(examId);
            if (exam != null) {
                Paper paper = paperMapper.selectById(exam.getPaperId());
                if (paper != null && paper.getPassScore() != null) {
                    long passCount = records.stream()
                            .filter(r -> r.getScore() != null && r.getScore().compareTo(paper.getPassScore()) >= 0)
                            .count();
                    statistics.setPassRate(new BigDecimal(passCount * 100).divide(
                            new BigDecimal(records.size()), 2, RoundingMode.HALF_UP));
                }
            }

            // 当前学生排名
            Optional<ExamStudentRecord> currentRecord = records.stream()
                    .filter(r -> r.getUserId().equals(userId))
                    .findFirst();

            if (currentRecord.isPresent() && currentRecord.get().getScore() != null) {
                long rank = records.stream()
                        .filter(r -> r.getScore() != null &&
                                r.getScore().compareTo(currentRecord.get().getScore()) > 0)
                        .count() + 1;
                statistics.setRank(rank);
            }
        }

        return statistics;
    }
}